/*
 * @Author: xiaosihan 
 * @Date: 2023-07-04 16:27:47 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-09-01 12:25:15
 */

import utils from "@utils";
import OSS from "ali-oss";
import axios, { CancelTokenSource } from "axios";
import { v4 as uuidv4 } from 'uuid';
import Api from "./Api";
import { get } from "lodash";
import { nanoid } from 'nanoid';
import { response } from "express";


// 公共接口
class UtilsApi extends Api {

    constructor() {
        super();
    }

    // oss 客户端
    ossClient?: OSS;

    // 上传凭证
    host = "";
    policy = "";
    ossAccessKeyId = "";
    signature = "";

    // 获取上传令牌中
    getkeying = false;

    // 获取文件扩展名
    getFileExtension = (filename: string) => {
        const regex = /\.(\w+)$/;
        const matches = filename.match(regex);
        return matches ? matches[1] : '';
    }


    //取消上传的oss
    sources: Array<CancelTokenSource> = [];
    cancelUploadOss() {
        while (this.sources.length) {
            this.sources.pop()?.cancel();
        }
    }

    //获取token获取文件
    getFile(url: string) {
        return this._get(url, {
            response: "arrayBuffer"
        });
    }

    // 获取osstoken
    async getOssToken() {

        const headers = {};
        if (localStorage.token) {
          Object.assign(headers, {
            Authorization: `Bearer ${localStorage.token}`,
          });
        }

        if ([this.host, this.policy, this.ossAccessKeyId, this.signature].some(v => v === "")) {
            // 获取oss 上传令牌
            const result = await axios({
                method: "post",
                baseURL: utils.isDev ? this.devBaseURL : this.baseURL,
                url: '/file/getOssToken',
                headers: headers,
            });

            //前端传到oss
            this.host = get(result, ["data", "data", "host"]);
            this.policy = get(result, ["data", "data", "policy"]);
            this.ossAccessKeyId = get(result, ["data", "data", "ossAccessKeyId"]);
            this.signature = get(result, ["data", "data", "signature"]);
            this.getkeying = false;
            // 在有效时间结束后销毁 oss 实例 以便从新获取令牌
            setTimeout(() => {
                this.ossClient = undefined;
                this.host = "";
                this.policy = "";
                this.ossAccessKeyId = "";
                this.signature = "";
            }, 1000 * 60 * 5);

        }
    }

    // 上传文件到 oss
    async uploadOss(file: File, onUploadProgress?: (progress: number) => void): Promise<any> {

        await this.getOssToken();

        const extension = this.getFileExtension(file.name);
        const fileName = `${utils.uuid()}.${extension}`;
        const formData = new FormData();
        formData.append("name", fileName);
        formData.append("policy", this.policy);
        formData.append("ossAccessKeyId", this.ossAccessKeyId);
        formData.append("success action status", "200");
        formData.append("signature", this.signature);
        formData.append("key", fileName);
        formData.append("file", file);

        const source2 = axios.CancelToken.source();
        this.sources.push(source2);

        const uploadResult = await axios({
            cancelToken: source2.token,
            method: "post",
            url: this.host,
            data: formData,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            onUploadProgress(e: any) {
                if (onUploadProgress) {
                    onUploadProgress(e.progress);
                }
            }
        });

        return `${this.host}/${fileName}`;

        // if (this.ossClient) {
        //     return await this.uploadOss(file);
        // } else {
        //     return await this.uploadOss(file);
        // }

    }

    async getUrlByOss(url: string) {

        await this.getOssToken();

        // 配置OSS客户端
        const client = new OSS({
            region: this.policy,
            accessKeyId: this.ossAccessKeyId,
            accessKeySecret: this.signature,
            bucket: '你的Bucket名称'
        });

        const ossUrl = client.signatureUrl(url, { expires: 3600 }); // 设置URL
        return ossUrl;
    }

}

const utilsApi = new UtilsApi();

export default utilsApi;

